package cn.bb.test;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.*;

public class GuiChat extends JFrame {
    public GuiChat(){
        setUpUI();
        initSocket();
        setListener();
    }
    private static final int DEFAULT_PORT=8899;
    //把主窗口分为NORTH，CEMTER和SOUTH
    private JLabel stateLB;//显示监听状态
    private JTextArea centerTextArea;//显示聊天记录
    private JPanel southPanel;//最下面的面板
    private JTextArea inputTextArea;//连天输入框
    private JPanel bottomPacel;//防止IP输入框，按钮等
    private JTextField ipTextField;//IP输入框
    private JTextField remotePortTF;//端口号输入框
    private JButton sendBT;//发送按钮
    private JButton clearBT;//清除聊天记录按钮
    private DatagramSocket datagramSocket;//用于后面功能实现

    private void setUpUI(){//图形化
        setTitle("聊天");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400,400);
        setResizable(false);
        setLocationRelativeTo(null);
        stateLB = new JLabel("当前还未启动监听");
        stateLB.setHorizontalAlignment(JLabel.RIGHT);

        centerTextArea = new JTextArea();
        centerTextArea.setEditable(false);
        centerTextArea.setBackground(new Color(211,211,211));

        southPanel = new JPanel(new BorderLayout());
        inputTextArea=new JTextArea(5,20);
        bottomPacel = new JPanel(new FlowLayout(FlowLayout.CENTER,5,5));
        ipTextField = new JTextField("127.0.0.1",8);
        remotePortTF = new JTextField(String.valueOf(DEFAULT_PORT),3);
        sendBT= new JButton("发送");
        clearBT = new JButton("清屏");
        bottomPacel.add(ipTextField);
        bottomPacel.add(remotePortTF);
        bottomPacel.add(sendBT);
        bottomPacel.add(clearBT);

        southPanel.add(new JScrollPane(inputTextArea),BorderLayout.CENTER);
        southPanel.add(bottomPacel,BorderLayout.SOUTH);

        add(stateLB,BorderLayout.NORTH);
        add(new JScrollPane(centerTextArea),BorderLayout.CENTER);
        add(southPanel,BorderLayout.SOUTH);
        setVisible(true);
    }
    private void setListener(){
        sendBT.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                final String ipAddress = ipTextField.getText();
                final String remoteport = remotePortTF.getText();
                if (ipAddress == null || "".equals(ipAddress.trim()) || remoteport==null || "".equals(remoteport.trim())){
                    JOptionPane.showMessageDialog(GuiChat.this,"请输入IP地址和端口号");
                    return;
                }
                if (datagramSocket == null || datagramSocket.isClosed()){
                    JOptionPane.showMessageDialog(GuiChat.this,"监听不成功！！！");
                    return;
                }
                String  sendContext = inputTextArea.getText();
                byte[] buf = sendContext.getBytes();
                try{
                    centerTextArea.append("我对"+ipAddress+":"+remoteport+"说：\n"+inputTextArea.getText()+"\n\n");
                    centerTextArea.setCaretPosition(centerTextArea.getText().length());
                    datagramSocket.send(new DatagramPacket(buf,buf.length, InetAddress.getByName(ipAddress),Integer.parseInt(remoteport)));
                    inputTextArea.setText("");
                }catch (IOException eq){
                    JOptionPane.showMessageDialog(GuiChat.this,"出错了发送失败");
                    eq.printStackTrace();
                }
            };
        });
        clearBT.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                centerTextArea.setText("");
            }
        });
    }
    private void initSocket(){
        int port = DEFAULT_PORT;
        while(true){
            try{
                if (datagramSocket != null && !datagramSocket.isClosed()){
                    datagramSocket.close();
                }
                try{
                    port = Integer.parseInt(JOptionPane.showInputDialog(this,"请输入端口号","端口号",JOptionPane.QUESTION_MESSAGE));
                    if (port<1 || port>65535){
                        throw new RuntimeException("端口超出范围");
                    }
                }catch (Exception e){
                    JOptionPane.showMessageDialog(null,"你输入的端口不正确，请输入1到65535之间的数");
                    continue;
                }
                datagramSocket = new DatagramSocket(port);
                startListen();
                stateLB.setText("已在"+port+"端口接听");
                break;
            }catch (SocketException e){
                JOptionPane.showMessageDialog(this,"端口已被占用，请重新设置端口");
                stateLB.setText("当前还未启动监听");
            }
        }
    }
    private void startListen(){
        new Thread(){
          private DatagramPacket p;
          public void  run(){
              byte[] buf = new byte[1024];
              p = new DatagramPacket(buf,buf.length);
              while(!datagramSocket.isClosed()){
                  try{
                      datagramSocket.receive(p);
                      centerTextArea.append(p.getAddress().getHostAddress()+":"+((InetSocketAddress)p.getSocketAddress()).getPort()+
                              "对我说：\n"+new String(p.getData(),0,p.getLength())+"\n\n");
                      centerTextArea.setCaretPosition(centerTextArea.getText().length());
                  }catch (IOException e){
                      e.printStackTrace();
                  }
              }
          }
        }.start();
    }

    public static void main(String[] args) {
        new GuiChat();
    }
}
